import urllib
import urllib2
import re
import logging
import cookielib
from google.appengine.api import memcache

import threading

class MyCookieJar(cookielib.CookieJar):
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['_cookies_lock']
        return state

    def __setstate__(self, state):
        self.__dict__ = state
        self._cookies_lock = threading.RLock()
        
class CyworldUrl:
    tid = None
    
    def __init__(self, id = None, tid = None, email = None, password = None):
        self._memcache = memcache.Client()
        
        self.tid = tid if tid is not None else self._get_tid_by_id(id)
        
        self._cookie_jar = self._memcache.get('%s_cj')
        if not self._cookie_jar:
            self._cookie_jar = MyCookieJar()
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cookie_jar))

        if email is not None and password is not None:
            logging.debug('Trying login.')
            self._login(email, password)
        else:
            logging.debug('Getting default session.')
            self._set_default_session()
        
    def _get_tid_by_id(self, id):
        cache_key = '%s_tid' % id
        tid = self._memcache.get(cache_key)
        if not tid:
            f = urllib2.urlopen("http://www.cyworld.com/%s" % id)
            m = re.search(r'pims\/main\/domain2\.asp\?tid=([0-9]+)', f.read())
            tid = m.group(1)
            self._memcache.add(cache_key, tid, 3600)
        return tid
    
    def get_tid(self):
        return self.tid
    
    def open(self, url, referer = 'http://minihp.cyworld.com/', params = None):
        logging.debug('opening url: %s' % url)
        self.opener.addheaders = [
                                  ('Referer', referer), 
                                  ('Host', url[url.find('//')+2:url.find('/', url.find('//')+2)]),
                                 ]
        f = self.opener.open(url, urllib.urlencode(params) if params is not None else None)
        cookie = f.info().getheader('set-cookie')
        if self._cookie_jar and cookie is not None and cookie.find('ASPSESSION') == -1:
            self._memcache.add(key = '%s_cj' % self.tid, value = self._cookie_jar, time=3600) # store last succeed cookie to memcache
            logging.debug('cookie: %s' % cookie)
        return f
                    
    def _set_default_session(self):
        self.open('http://sess.cyworld.com/link.asp')
        
    def _login(self, email, password):
        f = self.open('http://cyxso.cyworld.com/login.jsp', 'http://www.cyworld.com/pims/main/domain2.asp?tid=%s&login_yn=1' % self.tid, {
          'email': email, 
          'passwd': password, 
          'dest': '',
          'jcode': '',
          'pop': 'ok',
          'domain': '',
          'return_domain': 'cyworld.com',
        })
        if f.read().find('Input value length mismatching error') != -1:
            raise RuntimeError('Login failed. Email/Password are mismatching.')